{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Rate of Returns Over Multiple Periods\n",
    "\n",
    "## Numpy.cumsum and Numpy.cumprod\n",
    "\n",
    "\n",
    "You've just leared about active returns and passive returns.  Another important concept related to returns is \"Cumulative returns\" which is defined as the returns over a time period.  You can read more about rate of returns [here](https://en.wikipedia.org/wiki/Rate_of_return)! \n",
    "\n",
    "There are two ways to calcualte cumulative returns, depends on how the returns are calculated.  Let's take a look at an example.  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from datetime import datetime\n",
    "\n",
    "dates = pd.date_range(datetime.strptime('1/1/2016', '%m/%d/%Y'), periods=12, freq='M')\n",
    "start_price, stop_price = 0.24, 0.3\n",
    "abc_close_prices = np.arange(start_price, stop_price, (stop_price - start_price)/len(dates))\n",
    "\n",
    "abc_close = pd.Series(abc_close_prices, dates)\n",
    "abc_close"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, we have the historical prices for stock ABC for 2016.  We would like to know the yearly cumulative returns for stock ABC in 2016 using time-weighted method, assuming returns are reinvested.  How do we do it?  Here is the formula:\n",
    "\n",
    "Assume the returns over n successive periods are:\n",
    "\n",
    "$ r_1, r_2, r_3, r_4, r_5, ..., r_n $\n",
    "\n",
    "The cumulative return of stock ABC over period n is the compounded return over period n:\n",
    "\n",
    "$ (1 + r_1)(1 + r_2)(1 + r_3)(1 + r_4)(1 + r_5)...(1 + r_n) - 1 $\n",
    "\n",
    "First, let's calculate the returns of stock ABC.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "returns = abc_close / abc_close.shift(1) - 1\n",
    "returns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The cumulative return equals to the product of the daily returns for the n periods. \n",
    "That's a very long formula.  Is there a better way to calculate this.  \n",
    "\n",
    "\n",
    "The answer is yes, we can use numpy.cumprod().\n",
    "\n",
    "For example, if we have the following time series: 1, 5, 7, 10 and we want the product of the four numbers.  How do we do it?  Let's take a look!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lst = [1,5,7,10]\n",
    "np.cumprod(lst)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The last element in the list is 350, which is the product of 1, 5, 7, and 10.  \n",
    "\n",
    "OK, let's use numpy.cumprod() to get the cumulative returns for stock ABC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "(returns + 1).cumprod()[len(returns)-1] - 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The cumulative return for stock ABC in 2016 is 22.91%.\n",
    "\n",
    "The other way to calculate returns is to use log returns.\n",
    "\n",
    "The formula of log return is the following:\n",
    "\n",
    "$ LogReturn = ln(\\frac{P_t}{P_t - 1}) $\n",
    "\n",
    "The cumulative return of stock ABC over period n is the compounded return over period n:\n",
    "\n",
    "$ \\sum_{i=1}^{n} r_i = r_1 + r_2 + r_3 + r_4 + ... + r_n $\n",
    "\n",
    "Let's see how we can calculate the cumulative return of stock ABC using log returns.\n",
    "\n",
    "First, let's calculate log returns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "log_returns = (np.log(abc_close).shift(-1) - np.log(abc_close)).dropna()\n",
    "log_returns.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The cumulative sum equals to the sum of the daily returns for the n periods which is a very long formula.  \n",
    "\n",
    "To calculate cumulative sum, we can simply use numpy.cumsum().\n",
    "\n",
    "Let's take a look at our simple example of time series 1, 5, 7, 10. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lst = [1,5,7,10]\n",
    "np.cumsum(lst)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The last element is 23 which equals to the sum of 1, 5, 7, 10\n",
    "\n",
    "OK, let's use numpy.cumsum() to get the cumulative returns for stock ABC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cum_log_return = log_returns.cumsum()[len(log_returns)-1]\n",
    "np.exp(cum_log_return) - 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The cumulative return for stock ABC in 2016 is 22.91% using log returns."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quiz: Arithmetic Rate of Return\n",
    "\n",
    "Now, let's use cumprod() and cumsum() to calculate average rate of return.  \n",
    "\n",
    "For consistency, let's assume the rate of return is calculated as $ \\frac{P_t}{P_t - 1} - 1 $\n",
    "\n",
    "### Arithmetic Rate of Return:\n",
    "\n",
    "$ \\frac{1}{n} \\sum_{i=1}^{n} r_i = \\frac{1}{n}(r_1 + r_2 + r_3 + r_4 + ... + r_n) $"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import quiz_tests\n",
    "\n",
    "def calculate_arithmetic_rate_of_return(close):\n",
    "    \"\"\"\n",
    "    Compute returns for each ticker and date in close.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    close : DataFrame\n",
    "        Close prices for each ticker and date\n",
    "    \n",
    "    Returns\n",
    "    -------\n",
    "    arithmnetic_returns : Series\n",
    "        arithmnetic_returns at the end of the period for each ticker\n",
    "        \n",
    "    \"\"\"\n",
    "    # TODO: Implement Function\n",
    "    \n",
    "    return None\n",
    "\n",
    "\n",
    "quiz_tests.test_calculate_arithmetic_rate_of_return(calculate_arithmetic_rate_of_return)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quiz Solution\n",
    "If you're having trouble, you can check out the quiz solution [here](cumsum_and_cumprod_solution.ipynb)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
